package lookas;

import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.util.Vector;

import javax.microedition.io.Connector;
import javax.microedition.io.HttpConnection;

public class GoogleMaps {
	private static final String G_KEY = "ABQIAAAA1XuiPbKjPHJAKKEx9CKNHRSLWincOB-RnaOR21GrakbRhS5_HBTSiisl2F9Er4fx0o6MfSSN0HF0dQ";

	public Position geocodeAddress(String address) throws Exception {
		String geocodeUrl = getGeocodeUrl(address);
		byte[] res = loadHttpFile(geocodeUrl);
		String resString = new String(res, 0, res.length);
		String[] data = split(resString, ',');
		if (data[0].compareTo("200") != 0) {
			int errorCode = Integer.parseInt(data[0]);
			throw new Exception(getGeocodeError(errorCode));
		} else {
			Position ret = new Position();
			ret.address = address;
			ret.lat = Double.parseDouble(data[2]);
			ret.lon = Double.parseDouble(data[3]);
			return ret;
		}
	}

	private String getGeocodeError(int errorCode) {
		switch (errorCode) {
		case 400:
			return "Bad request";
		case 500:
			return "Server error";
		case 601:
			return "Missing query";
		case 602:
			return "Unknown address";
		case 603:
			return "Unavailable address";
		case 604:
			return "Unknown directions";
		case 610:
			return "Bad API key";
		case 620:
			return "Too many queries";
		default:
			return "Generic error";
		}
	}

	private String getGeocodeUrl(String address) {
		return "http://maps.google.com/maps/geo?output=csv&key=" + G_KEY
				+ "&q=" + urlEncode(address);
	}

	private String urlEncode(String str) {
		StringBuffer buf = new StringBuffer();
		char c;
		for (int i = 0; i < str.length(); i++) {
			c = str.charAt(i);
			if ((c >= '0' && c <= '9') || (c >= 'A' && c <= 'Z')
					|| (c >= 'a' && c <= 'z')) {
				buf.append(c);
			} else {
				buf.append("%")
						.append(Integer.toHexString((int) str.charAt(i)));
			}
		}
		return buf.toString();
	}

	private byte[] loadHttpFile(String url) throws Exception {
		HttpConnection hc = null;
		InputStream is = null;
		byte[] byteBuffer = null;
		try {
			hc = (HttpConnection) Connector.open(url);
			hc.setRequestMethod(HttpConnection.GET);
			int ch;
			is = hc.openInputStream();
			int len = (int) hc.getLength();
			if (len > 0) {
				byteBuffer = new byte[len];
				is.read(byteBuffer);
			} else {
				ByteArrayOutputStream bos = new ByteArrayOutputStream();
				while ((ch = is.read()) != -1) {
					bos.write(ch);
				}
				byteBuffer = bos.toByteArray();
				bos.close();
			}
		} finally {
			if (is != null)
				is.close();
			if (hc != null)
				hc.close();
		}
		return byteBuffer;
	}

	private static String[] split(String s, int chr) {
		Vector res = new Vector();
		int curr = 0;
		int prev = 0;
		while ((curr = s.indexOf(chr, prev)) >= 0) {
			res.addElement(s.substring(prev, curr));
			prev = curr + 1;
		}
		res.addElement(s.substring(prev));
		String[] splitted = new String[res.size()];
		res.copyInto(splitted);
		return splitted;
	}
}